﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
using SevenZip;
using System.Drawing.Imaging;

namespace Screener.Imaging
{
    public class Logger
    {
        private System.Timers.Timer timer;
        private Bitmap bmp;
        private Graphics g;
        private Buffer buffer;
        private bool active;

        public static int CellInfos;

        public string Message { get; set; }

        public Size FrameSize
        {
            get
            {
                return buffer.Size;
            }
            set
            {
                buffer.Size = value;
            }
        }

        public Size ScreenSize { get; set; }

        public int Interval
        {
            get
            {
                return (int)timer.Interval;
            }
            set
            {
                timer.Interval = value;
            }
        }

        public string FileName { get; set; }

        public Logger(Size frameSize, Size screenSize, int interval)
        {
            this.ScreenSize = screenSize;

            this.FileName = "Logger.dat";

            buffer = new Buffer(frameSize, this.ScreenSize);

            bmp = new Bitmap(this.ScreenSize.Width, this.ScreenSize.Height, PixelFormat.Format24bppRgb);
            g = Graphics.FromImage(bmp);

            timer = new System.Timers.Timer();
            this.Interval = interval;
            timer.AutoReset = false;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        }

        public void Start()
        {
            active = true;
            Shot();
            timer.Start();
        }

        public void Stop()
        {
            active = false;
            timer.Stop();

            System.Threading.Thread.Sleep(1000);

            this.Save();
        }

        public void Save()
        {
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

            if (File.Exists("7z.dll"))
            {
                SevenZipCompressor.SetLibraryPath(Path.GetFullPath("7z.dll"));
            }

            if (File.Exists(this.FileName))
            {
                File.Delete(this.FileName);
            }

            Logger.CellInfos = 0;

            using (FileStream fs = File.Open(this.FileName, FileMode.OpenOrCreate & FileMode.Truncate))
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    buffer.Cells.Sort((x, y) => Cell.Compare(x, y));

                    buffer.Write(ms);

                    SevenZipCompressor compressor = new SevenZipCompressor();
                    compressor.CompressionMethod = SevenZip.CompressionMethod.Lzma2;
                    compressor.CompressionLevel = SevenZip.CompressionLevel.Ultra;

                    ms.Position = 0;

                    compressor.CompressStream(ms, fs);
                }
            }

            FileInfo fi = new FileInfo(this.FileName);

            this.Message = string.Format("Frames: {0}\r\nAverage Size:{1}", buffer.Index, ((double)(fi.Length / 1024)) / (double)buffer.Index);
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                if (active)
                {
                    Shot();
                    timer.Start();
                }
            }
            catch
            {
                //don't know
            }
        }

        private void Shot()
        {
            g.CopyFromScreen(0, 0, 0, 0, this.ScreenSize, CopyPixelOperation.SourceCopy);
            buffer.Add(bmp);
        }
    }
}
